/**
 * @brief FreeRTOS应用示例
 * @details
 * @author 王炸物联网https://blog.csdn.net/wangyx1234?spm=1000.2115.3001.5343
 * @date 2022
 * @version 1.0
 * @copyright 版权所有，禁止用于商业用途
 */
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_log.h"

typedef struct {
    uint32_t counter; // 计数器
    uint32_t counter_ten_place; // 计数器的十位数字
} capture_counter_t;

TaskHandle_t task1; // 任务1结构对象
TaskHandle_t task2;
TaskHandle_t task3;

static capture_counter_t cap_counter;
static uint32_t s_share_counter = 0;                  // 全局共享计数器

/**
 * 初始化共享计数器
 * @param count 初始的计数器
 */
void share_counter_init (uint32_t count)
{
    s_share_counter = count;
}

void share_counter_process(bool flag)
{
    if(flag) {
        uint32_t var1 = s_share_counter;
        var1 = var1 + 1;
        vTaskDelay(pdMS_TO_TICKS(1000));     // 模拟被其它任务打断
        s_share_counter = var1;
    } else {
        uint32_t var2 = s_share_counter;
        var2 = var2 - 1;
        vTaskDelay(pdMS_TO_TICKS(1000));     // 模拟被其它任务打断
        s_share_counter = var2;
    }
}

/**
 * 获取共享计数器值
 * @return 当前计数值
 */
uint32_t get_share_counter(void) 
{
    return s_share_counter;
}

/**
 * 任务的运行代码
 * @param param 任务初始运行参数
 */
static void task1_process(void *arg)
{
    while (1) {
        share_counter_process(true);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

static void task2_process(void *arg)
{
    while (1) {
        share_counter_process(false);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

static void task3_process(void *arg)
{
    while (1) {
        cap_counter.counter = cap_counter.counter + 4;
        vTaskDelay(pdMS_TO_TICKS(500)); // 模拟更新结构体其他成员时被打断
        cap_counter.counter_ten_place = cap_counter.counter / 10 % 10;
    }
    vTaskDelete(NULL);
}

static void init(void) {
    printf("Hello world!\n");

    /* Print chip information */
    esp_chip_info_t chip_info;
    esp_chip_info(&chip_info);
    printf("This is %s chip with %d CPU core(s), WiFi%s%s, ",
            CONFIG_IDF_TARGET,
            chip_info.cores,
            (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
            (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");

    printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
}

void app_main(void)
{
    init();
    /*
    static BaseType_t xTaskCreate(TaskFunction_t pvTaskCode, const char *constpcName, const uint32_t usStackDepth, 
    void *constpvParameters, UBaseType_t uxPriority, TaskHandle_t *constpxCreatedTask)*/
    xTaskCreate(&task1_process, "task1", 1024*2, (void *)"1", configMAX_PRIORITIES-1, &task1); // configMAX_PRIORITIES = 25
    xTaskCreate(&task2_process, "task2", 1024*2, (void *)"2", configMAX_PRIORITIES-1, &task2);
    xTaskCreate(&task3_process, "task3", 1024*2, (void *)"3", configMAX_PRIORITIES-2, &task3);

    while (1) {
        printf("share_counter = %u\r\n", s_share_counter);
        printf("cap_counter.counter = %u, ten_place = %u\r\n", cap_counter.counter, cap_counter.counter_ten_place);
        vTaskDelay(pdMS_TO_TICKS(900));
    }
}
